package com.naja.event.tracking.extract.observer;

import com.naja.event.tracking.extract.domain.TBaseEvent;
import com.naja.event.tracking.extract.domain.TBizEvent;
import com.naja.event.tracking.extract.domain.TEventTraceAggregated;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @auther wangjianying
 * @date 2023/09/19 11:00
 */
public class SimpleBase2bizExtractObserver implements Base2bizExtractObserver{
    private List<String> sortedTagEvents;
    private String eventName;
    private String eventDesc;
    private TagEventNode currentTagEventNode;
    private Date bizEventBeginTime;
    private Date bizEventEndTime;
    private List<TBizEvent> tBizEvents;

    public SimpleBase2bizExtractObserver(List<String> sortedTagEvents, String eventName, String eventDesc) {
        this.sortedTagEvents = sortedTagEvents;
        this.eventName = eventName;
        this.eventDesc = eventDesc;
        this.tBizEvents = new ArrayList<>();
        if (sortedTagEvents != null && !sortedTagEvents.isEmpty()) {
            TagEventNode prev = null;
            for (String sortedTagEvent : sortedTagEvents) {
                prev = new TagEventNode(prev, sortedTagEvent);
            }
            currentTagEventNode = prev.getFirst();
        }
    }
    public int status(){
        if (currentTagEventNode.isFirst()) {
            return 0;
        }else{
            return 1;
        }
    }
    public void update(TEventTraceAggregated tEventTraceAggregated, TBaseEvent tBaseEvent) {
        String rooterName = tBaseEvent.getRooterName();
        if (!StringUtils.isEmpty(rooterName)) {
            if(currentTagEventNode.getFirst().equals(rooterName)){
                currentTagEventNode = currentTagEventNode.getFirst();
            }
            if (currentTagEventNode.item.equals(rooterName)) {
                if (currentTagEventNode.isFirst()) {
                    bizEventEndTime = tBaseEvent.getActionTime();
                }
                if (currentTagEventNode.isLast()) {
                    bizEventBeginTime = tBaseEvent.getActionTime();
                    currentTagEventNode = currentTagEventNode.getFirst();
                    TBizEvent tBizEvent = new TBizEvent(tEventTraceAggregated);
                    tBizEvent.setEventName(eventName);
                    tBizEvent.setEventDesc(eventDesc);
//                    tBizEvent.setBizType();
                    tBizEvent.setActionBeginTime(bizEventBeginTime);
                    tBizEvent.setActionEndTime(bizEventEndTime);
                    this.tBizEvents.add(tBizEvent);
                } else {
                    currentTagEventNode = currentTagEventNode.next;
                }
            }
        }
    }

    public List<TBizEvent> getResult() {
        return tBizEvents;
    }

    @Override
    public void init() {
        currentTagEventNode = currentTagEventNode.getFirst();
        bizEventBeginTime = null;
        bizEventEndTime = null;
        tBizEvents.clear();
    }

    public List<String> getSortedTagEvents() {
        return sortedTagEvents;
    }

    public void setSortedTagEvents(List<String> sortedTagEvents) {
        this.sortedTagEvents = sortedTagEvents;
    }

    public void reset() {
        currentTagEventNode = currentTagEventNode.getFirst();
    }

    private class TagEventNode {
        String item;
        TagEventNode next;
        TagEventNode prev;

        TagEventNode(TagEventNode prev, String item) {
            this.item = item;
            if (prev != null) {
                this.prev = prev;
                this.prev.next = this;
            }
        }

        public TagEventNode getFirst() {
            if (this.prev == null) {
                return this;
            }
            return prev.getFirst();
        }

        public TagEventNode getLast() {
            if (this.next == null) {
                return this;
            }
            return next.getLast();
        }

        public boolean isFirst() {
            return this.prev == null;
        }
        public boolean isLast() {
            return this.next == null;
        }
    }
}
